<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>观察者模式题一</title>
</head>
<body>
<script>
//    测试1
//    Event.on('test', function (result) {
//        console.log(result);
//    });
//    Event.on('test', function () {
//        console.log('test');
//    });
//    Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'

    function EventTarget(){
        //创建一个对象
        this.handles={};
    }
    //将方法添加到原型上
    EventTarget.prototype={
        constructor:EventTarget,
        addHandle:function(type,handler){
            //先判断这个回调是否存在
            if(typeof this.handles[type]=="undefined"){
                this.handles[type]=[];
            }
            //把回调push进去
            this.handles[type].push=[];
        },
        fire:function(event){
            if(!event.target){
                //如果不存在event.target,改变this指向
                event.target=this;
            }
            if(this.handles[event.type] instanceof Array){
                //如果是数组的话就要去遍历他
                var handles=this.handles[event.type];
                for(var i=0,len=handles.length;i<len;i++){
                    //遍历去调用回调函数
                    handles[i](event);
                }
            }
        },
        removeHandle:function(type,handler){
            if(this.handles[type] instanceof Array){
                var handlers=this.handles[type];
                for(var i=0,len=handlers.length;i<len;i++){
                    if(handlers[i]===handler){
                        break;
                    }
                }
                handlers.splice(i,1);
            }
        }
    }

    var Event={
        //通过on接口监听事件eventName
        //如果时间eventName被触发，则执行callback回调函数
        on:function(eventName,callback){
            //先判断是否有handles这存放函数和key的对象，没有先创建
            if(!this.handles){
                this.handles={};
            }
            //再判断是否是否有这叫eventName的值，没有则创建一个
            if(!this.handles[eventName]){
               this.handles[eventName]=[];
            }
            //把callback放进去
            this.handles[eventName].push(callback);
        },
        emit:function(eventName){
            if(this.handles[arguments[0]]){
                for(var i=0;i<this.handles[arguments[0]].length;i++){
                    //遍历掉用回调
                    this.handles[arguments[0]][i](arguments[1]);
                }
            }
        },
        remove:function(eventName,callback){
            if(this.handles[eventName] instanceof  Array){
                var handles=this.handles[eventName];
                for(var i=0,len=handles.length;i<len;i++){
                    if(handles[i]==callback){
                        break;
                    }
                }
                handles.splice(i,1);
            }
        }
    };
    function fn(result){
        console.log(result+"你好，世界")
    }
    Event.on("call1",fn);
    Event.emit("call1","hello world!");
    Event.remove("call1",fn);
    Event.emit("call1","hello world!");

    Event.on("call2",fn);
    Event.emit("call2","hello !");
//测试二
//var person1 = {};
//var person2 = {};
//Object.assign(person1, Event);
//Object.assign(person2, Event);
//person1.on('call1', function () {
//    console.log('person1');
//});
//person2.on('call2', function () {
//    console.log('person2');
//});
//person1.emit('call1'); // 输出 'person1'
//person1.emit('call2'); // 没有输出
//person2.emit('call1'); // 没有输出
//person2.emit('call2'); // 输出 'person2'

//
    var Event2={
        //通过on接口监听事件eventName
        //如果时间eventName被触发，则执行callback回调函数
        //为啥这样写呢，因为上面那种是引用模式，会互相影响
        on:function(eventName,callback){
            if(!this.handles){
                Object.defineProperty(this,"handles",{
                    value:{},
                    enumerable:false,
                    configurable:true,
                    writable:true
                })
            }
            if(!this.handles[eventName]){
                this.handles[eventName]=[];
            }
            this.handles[eventName].push(callback);
        },
        //触发事件
        emit:function(eventName){
            if(this.handles[arguments[0]]){
                for(var i=0;i<this.handles[arguments[0]].length;i++){
                    //遍历掉用回调
                    this.handles[arguments[0]][i](arguments[1]);
                }
            }
        },
    }



</script>
</body>
</html>